package com.foo.designpattern.proxy.dynamicproxy1.cglibdynamicproxy1;


import junit.framework.TestCase;

/**
 * com.foo.designpattern.proxy.dynamicproxy1.cglibdynamicproxy1
 * Created with IntelliJ IDEA.
 * Created by jiang on 2016-04-29 23:15.
 *
 * @Description 测试类：cglib动态代理
 * JDK的动态代理机制只能代理实现了接口的类，而不能实现接口的类就不能实现JDK的动态代理。
 * cglib是针对类来实现代理的，他的原理是对指定的目标类生成一个子类，并覆盖其中方法实现增强，
 * 但因为cglib采用的是继承，所以不能对final修饰的类进行代理。
 * JDK的动态代理创建机制----通过接口； cglib 生成动态代理类的机制----通过类继承。
 * <p/>
 * cglib 创建某个类A的动态代理类的模式是：
 * 1、查找A上的所有非final 的public类型的方法定义；
 * 2、将这些方法的定义转换成字节码；
 * 3、将组成的字节码转换成相应的代理的class对象；
 * 4、实现 MethodInterceptor 接口，用来处理对代理类上所有方法的请求（这个接口和JDK动态代理InvocationHandler的功能和角色是一样的）。
 */

public class CglibDynamicProxy1TestCase extends TestCase {
    public void testCglibDynamicProxy1() {
        System.out.println("= = = = ↓↓↓代理模式：cglib动态代理，测试开始↓↓↓ = = = =");

        FilterHandler filterHandler = new FilterHandler();
        // 注意cglib.getInstance()的参数及接收返回值的类型
        System.out.println("= = = = = = = = = = = = 分割线 = = = = = = = = = = = = ");

        // 实现接口
        Action action1 = (Action) filterHandler.getInstance(new SecondAction());
        action1.excute("实现接口，使用接口");
        System.out.println("= = = = = = = = = = = = 分割线 = = = = = = = = = = = = ");

        // 实现接口
        SecondAction secondAction = (SecondAction) filterHandler.getInstance(new SecondAction());
        secondAction.excute("实现接口，不使用接口");
        System.out.println("= = = = = = = = = = = = 分割线 = = = = = = = = = = = = ");

        // 没有实现接口
        FirstAction firstAction = (FirstAction) filterHandler.getInstance(new FirstAction());
        firstAction.excute("未实现接口，不使用接口");
        System.out.println("= = = = = = = = = = = = 分割线 = = = = = = = = = = = = ");

        /**
         * 在java语言中，给出了3种处理系统错误的机制。
         * 1、抛出一个异常；
         * 2、日志；
         * 3、使用断言。
         */
        // 没有实现接口，会报错
        try {
            Action action2 = (Action) filterHandler.getInstance(new FirstAction());
            action2.excute("未实现接口，使用接口");
        } catch (ClassCastException e) {
            System.out.println("未实现接口，使用接口，导致类型转换错误啦。\n【解救强迫症,重现小绿条】");
            e.printStackTrace();
        }

        System.out.println("= = = = ↑↑↑代理模式：cglib动态代理，测试结束↑↑↑ = = = =");
    }
}
